package org.fujene.communicate;

import java.util.SortedSet;
import java.util.concurrent.TimeUnit;

import org.fujene.communicate.node.Node;
import org.fujene.communicate.rpc.Communicator;
import org.fujene.logging.LogParser;

public class BeaconService extends Thread{
	private SortedSet<Node> nodeList;
	private Node myNode;
	private MainService mains;
	private Communicator communicator;
	private int interval;
	private int suspension;
	private boolean stopFlag = false;

	public BeaconService(Node myNode, SortedSet<Node> nodeList, MainService nodeSrv,
			int beaconInterval, int suspension, Communicator communicator){
		this.myNode = myNode;
		this.nodeList = nodeList;
		this.mains = nodeSrv;
		this.interval = beaconInterval;
		this.suspension = suspension;
		this.communicator = communicator;
	}

	public void stopRunning(){
		stopFlag = true;
	}

	@Override
	public void run(){
		while(true){
			boolean isLiveSignal;

			for(Node eachNode: nodeList){
				if(eachNode.equals(myNode)) continue;
//				System.out.println("See " + eachNode.getAddr() + ":" + eachNode.getPort());
				if(eachNode.isSuspend()){
					if(!eachNode.isExceedsTimeLimit()) continue;
					mains.deleteReplication(eachNode.getAddr(), eachNode.getPort());
				}
				try{
					isLiveSignal = communicator.isLive(eachNode);
					if(!isLiveSignal){
						// Determine as called node is dead -> suspend
						if(eachNode.isDead()) mains.suspend(eachNode.getAddr(), eachNode.getPort(), suspension);
					}else eachNode.live();
					if(stopFlag) communicator.finalizeProcess(eachNode, myNode);
				}catch(Exception e){
					LogParser.info(String.format("Node %s seems to be dead.", eachNode.getAddr()));
					// Determine as called node is dead
//					mains.deleteReplication(eachNode.getAddr(), eachNode.getPort());
					mains.suspend(eachNode.getAddr(), eachNode.getPort(), suspension);
				}
			}
			if(stopFlag) break;
			try{
				TimeUnit.SECONDS.sleep(interval);
			}catch(InterruptedException ignored){}
		}
	}
}
